// //Object.create(proto，[propertiesObject])：创建一个对象，第一个参数为新对象的原型对象
// //第二个参数可配置新对象自身的属性
// let obj = Object.create({ a: 1 }, {
//   b: {
//     value:2,   //属性值
//     enumerable: true,  //是否可枚举
//     writable: true,     //是否可以重写值
//     configurable: true  //是否可以修改以上几项配置
//   }
// })
// console.log(obj)  //{ b: 2 }
// console.log(obj.__proto__);  //{ a: 1 }
//
// Object.defineProperty(obj, prop, descriptor)：
// 在指定对象上定义一个新属性或者修改一个属性，并进行
// 相应配置，第一个参数为配置的对象，第二个参数为要定义
// 或修改的属性名，第三个属性为属性描述符
// value：属性值
// writable：定义是否可重写，默认为false
// enumerable：定义是否可枚举，默认为false
// configurable：定义描述符是否可以改变，默认为false
// get：属性的getter函数，访问属性时会执行此函数，默认为undefine
// set：属性的setter函数，修改属性时，会调用此函数，默认为undefined
// 属性描述符分为：数据描述符和存取描述符，数据描述符是一个具有值的属性，该值可以是可写的，也可以是不可写的
// 存取描述符是由getter函数和setter函数所描述的属性，如果一个描述符同时拥有 value 或 writable 和 get 或 set 键，则会产生一个异常。
// let obj = {};
// Object.defineProperty(obj, 'a', {
//   value: 1,
//   writable: true,  //定义是否可重写
//   enumerable: true,   //定义是否可枚举
//   configurable: true,  //定义是否可配置
// })
//
// //Object.assign(target, ...sources)：将一个或多个对象的可枚举属性分配到目标对象，并返回目标对象。
// const target = {a: 1};
// const obj = Object.assign(target, {b: 3}, {b: 4, c: 5});
// console.log(obj);  //{ a: 1, b: 4, c: 5 } 注意后面的源对象属性会覆盖前面的
//
// // Object.freeze：冻结一个对象，冻结后便不能被修改，
// // 不能添加新属性，也不能删除属性，不能修改属性描述符，
// // 原型也不能修改。
// // 但是如果一个属性的值是个对象，则这个对象中的属性是可以修改的，除非它也是个冻结对象
// // 如果一个属性的值是数组
// let obj = {
//   a: 1,
//   object: {
//     b: 5,
//   },
// }
// Object.freeze(obj);
// obj.a = 2;
// console.log(obj.a);  // 1
// obj.object.b = 6
// console.log(obj.object)  // { b: 6 }
//
// // Object.getOwnPropertyDescriptor：返回指定对象上一个自有属性对应的属性描述符，不能是原型上的。
// let obj = { a: 1 };
// let des = Object.getOwnPropertyDescriptor(obj, 'a');
// console.log(des.value);  // 1
// console.log(des.writable);// true
//
// // Object.getOwnPropertyNames：返回指定对象自身（不包括原型）所有的属性名（包括可枚举和不可枚举）组成的数组
// let obj = {a:1, b:2};
// let res = Object.getOwnPropertyNames(obj);
// console.log(res);  // [ 'a', 'b' ]
//
// // Object.getPrototypeOf：返回指定对象的原型对象
// let obj = {a: 1};
// obj.__proto__ = {b:2};
// console.log(Object.getPrototypeOf(obj));  // { b: 2 }
//
// // Object.is：比较两个值是否相等，除了NaN，+0和-0之外，其他与===相同
// console.log(+0 === -0);  //true
// console.log(NaN === NaN);  //false
// console.log(Object.is(+0, -0));  //false
// console.log(Object.is(NaN, NaN));  //true
//
// // Object.seal：密封一个对象，不能添加新属性以及当前属性不可配置，但是属性值得可写性不变
// let obj = { a: 1 };
// Object.seal(obj);
// obj.a = 2;
// obj.b = 3;
// console.log(obj.a);  //2
// console.log(obj.b);  //undefined
//
// //Object.preventExtensions：让一个对象变得不可扩展，不能添加新属性
// let obj = { a: 1 };
// Object.preventExtensions(obj);
// obj.b = 2;
// console.log(obj.b)  //undefined
//
// // Object.isExtensible：判断一个对象是否可以扩展
// // Object.preventExtensions，Object.seal 或 Object.freeze 方法都可以标记一个对象为不可扩展
// let obj = { a: 1 };
// Object.freeze(obj);
// obj.b = 2;
// console.log(obj.b);  //undefined
//
// // Object.keys：返回对象自身（不包括原型）可枚举属性组成的数组
// let obj = {
//   name: 'jack',
//   age: 13,
//   __proto__: {
//     address: 'abc',
//   }
// }
// console.log(Object.keys(obj))  //[ 'name', 'age' ]
//
// //Object.values：返回对象自身（不包括原型）可枚举属性值组成的数组
// let obj = {
//   name: 'jack',
//   age: 13,
//   __proto__: {
//     address: 'abc',
//   }
// }
// console.log(Object.values(obj))  //[ 'jack', 13 ]
//
// // Object.entries：返回对象自身（不包括原型）可枚举属性的键值对数组
// let obj = {
//   name: 'jack',
//   age: 13,
//   __proto__: {
//     address: 'abc',
//   }
// }
// console.log(Object.entries(obj))  //[ [ 'name', 'jack' ], [ 'age', 13 ] ]
